﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MathLab.Messaging;

namespace MathLab.Utils
{
  class MatrixMultiply
  {
    /// <summary>
    /// Multiply given matrixes
    /// </summary>
    /// <remarks>Given matrixes must have the same dimensions</remarks>
    /// <param name="matrixA"></param>
    /// <param name="matrixB"></param>
    /// <returns></returns>
    public static double[,] Multiply(double[,] matrixA, double[,] matrixB)
    {
      if (matrixA.GetLength(1) == matrixB.GetLength(0))
      {
        double[,] matrixResult = new double[matrixA.GetLength(0), matrixB.GetLength(1)];
        for (int i = 0; i < matrixA.GetLength(0); i++)
        {
          for (int j = 0; j < matrixB.GetLength(1); j++)
          {
            double dTempSum = 0;
            for (int k = 0; k < matrixA.GetLength(1); k++)
            {
              dTempSum += matrixA[i, k] * matrixB[k, j];
            }
            matrixResult[i, j] = dTempSum;
          }
        }
        return matrixResult;
      }
      else
      {
        throw new Exception("Could not multiply matrixes: Length of row of the first matrix is not equal to length of column of the second matrix");
      }
    }
    /// <summary>
    /// Multiplying vector by vector
    /// </summary>
    /// <param name="vectorA"></param>
    /// <param name="vectorB"></param>
    /// <returns>matrix</returns>
    public static double[,] Multiply(double[] vectorA, double[] vectorB)
    {
      if (MatrixCorrectness.CheckMatrixDim(vectorA,vectorB))
      {
        double[,] matrixResult = new double[vectorA.GetLength(0), vectorB.GetLength(0)];
        for (int i = 0; i < vectorA.Length; i++)
        {
          for (int j = 0; j < vectorB.Length; j++)
          {
            matrixResult[i, j] = vectorA[i] * vectorB[j];
          }
        }
        return matrixResult;
      }
      else
      {
        throw new Exception("Could not multiply vectors: They are not the same length");
      }
      
    }
    /// <summary>
    /// Multiply vector by matrix
    /// </summary>
    /// <param name="vector"></param>
    /// <param name="matrix"></param>
    /// <returns>matrix</returns>
    public static double[,] Multiply(double[] vector, double[,] matrix)
    {
      if (vector.Length == matrix.GetLength(0))
      {
        double[,] matrixResult = new double[vector.GetLength(0), matrix.GetLength(0)];
        for (int i = 0; i < matrix.GetLength(0); i++)
        {
          for (int j = 0; j < matrix.GetLength(1); j++)
          {
            double dTempSum = 0;
            for (int k = 0; k < matrix.GetLength(0); k++)
            {
              dTempSum += matrix[i, k] * vector[i];
            }
            matrixResult[i, j] = dTempSum;
          }
        }
        return matrixResult;
      }
      else
      {
        throw new Exception("Could not multiply: Vector and matrix's row are not the same length");
      }
    }

  }
}
